package com.smsc.headend.task.engine.handler.impl.deviceconfig;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.HexUtil;
import com.smsc.headend.common.enums.errorcode.TaskHandlerErrorCode;
import com.smsc.headend.common.utils.CosemUtils;
import com.smsc.headend.common.utils.CustomStringUtils;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.data.enums.OperationName;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.template.tou.entity.*;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import com.smsc.headend.task.engine.service.FeignAssetManagementService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * 20类 Activity Calendar (读取tou)
 * @author wxh
 * @date 2020/12/31 15:17
 */
@Slf4j
public class ReadActiveCalendarHandler implements TaskHandler {
    public static final String SUB_TASK_COMPLETED = "subTaskCompleted";
    @Autowired
    CosemXmlService cosemXmlService;
    @Autowired
    FeignAssetManagementService assetManagementService;
    @Autowired
    TaskDAO taskDAO;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException(TaskHandlerErrorCode.DEVICE_DATA_TYPE_NOT_SUPPORT.toString());
        }
        CosemData cosemData = (CosemData) deviceData;
        OperationName operationName = OperationName.forId(atomicTask.getOperationId());
        switch (operationName) {
            case GetCalendarNameActive:
            case GetCalendarNamePassive:
                Object data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), HexUtil.decodeHexStr((String)data), 600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)){
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true,600L, true);
                }
                break;
            case GetDayProfileActive:
            case GetDayProfilePassive:
                List<TemplateTouDayEntity> dayProfileList = new ArrayList<>();
                List<CosemData> dayProfileDatas = cosemData.getChild();
                for (CosemData dayProfileData:dayProfileDatas) {
                    List<CosemData> childDayProfile = dayProfileData.getChild();
                    if (childDayProfile.size() == 2) {
                        Integer dayId = Convert.toInt(cosemXmlService.getData(childDayProfile.get(0).getType(), childDayProfile.get(0).getValue()));
                        TemplateTouDayEntity dayEntity = new TemplateTouDayEntity();
                        dayEntity.setDayId(Long.valueOf(dayId));

                        List<CosemData> daySchedule = childDayProfile.get(1).getChild();
                        List<TemplateTouDayIntervalEntity> times = new ArrayList<>();
                        for (CosemData dayProfileActionData: daySchedule){
                            List<CosemData> dayProfileAction = dayProfileActionData.getChild();
                            if (dayProfileAction.size() == 3) {
                                String startTime = (String) cosemXmlService.getData(dayProfileAction.get(0).getType(), dayProfileAction.get(0).getValue());
                                String scriptLogicalName = (String) cosemXmlService.getData(dayProfileAction.get(1).getType(), dayProfileAction.get(1).getValue());
                                Integer scriptSelector = Convert.toInt(cosemXmlService.getData(dayProfileAction.get(2).getType(), dayProfileAction.get(2).getValue()));

                                TemplateTouDayIntervalEntity dayIntervalEntity = new TemplateTouDayIntervalEntity();
                                startTime = StringUtils.substring(CosemUtils.parseOctStringTime(startTime), 0,5); //截取显示hh:mm
                                dayIntervalEntity.setStartTime(startTime);
                                dayIntervalEntity.setScriptLogicalName(CustomStringUtils.parseHexObisCodeToInt(scriptLogicalName));
                                dayIntervalEntity.setScriptSelector(String.valueOf(scriptSelector));

                                times.add(dayIntervalEntity);
                            }
                        }
                        dayEntity.setTimes(times);
                        dayProfileList.add(dayEntity);
                    }
                }
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), dayProfileList,600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)){
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true,600L, true);
                }
                break;
            case GetWeekProfileActive:
            case GetWeekProfilePassive:
                List<TemplateTouWeekEntity> weekProfileList= new ArrayList<>();
                List<CosemData> weekProfileDatas = cosemData.getChild();
                for (CosemData weekProfileData: weekProfileDatas) {
                    List<CosemData> childWeekProfile = weekProfileData.getChild();
                    if (childWeekProfile.size() == 8) {
                        String weekProfileName = (String) cosemXmlService.getData(childWeekProfile.get(0).getType(), childWeekProfile.get(0).getValue());
                        Integer monday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(1).getType(), childWeekProfile.get(1).getValue()));
                        Integer tuesday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(2).getType(), childWeekProfile.get(2).getValue()));
                        Integer wednesday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(3).getType(), childWeekProfile.get(3).getValue()));
                        Integer thursday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(4).getType(), childWeekProfile.get(4).getValue()));
                        Integer friday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(5).getType(), childWeekProfile.get(5).getValue()));
                        Integer saturday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(6).getType(), childWeekProfile.get(6).getValue()));
                        Integer sunday = Convert.toInt(cosemXmlService.getData(childWeekProfile.get(7).getType(), childWeekProfile.get(7).getValue()));
                        TemplateTouWeekEntity weekEntity = new TemplateTouWeekEntity();
                        weekEntity.setWeekName(HexUtil.decodeHexStr(weekProfileName)).setMondayId(Long.valueOf(monday)).setTuesdayId(Long.valueOf(tuesday)).setWednesdayId(Long.valueOf(wednesday))
                                .setThursdayId(Long.valueOf(thursday)).setFridayId(Long.valueOf(friday)).setSaturdayId(Long.valueOf(saturday)).setSundayId(Long.valueOf(sunday));
                        weekProfileList.add(weekEntity);
                    }
                }
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), weekProfileList, 600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)){
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true,600L, true);
                }
                break;
            case GetSeasonProfileActive:
            case GetSeasonProfilePassive:
                List<TemplateTouSeasonEntity> seasonProfileList = new ArrayList<>();
                List<CosemData> seasonProfileDatas = cosemData.getChild();
                for (CosemData seasonProfileData:seasonProfileDatas) {
                    List<CosemData> childSeasonProfile = seasonProfileData.getChild();
                    if (childSeasonProfile.size() == 3) {
                        String seasonProfileName = (String) cosemXmlService.getData(childSeasonProfile.get(0).getType(), childSeasonProfile.get(0).getValue());
                        String seasonStart = (String) cosemXmlService.getData(childSeasonProfile.get(1).getType(), childSeasonProfile.get(1).getValue());
                        String weekName = (String) cosemXmlService.getData(childSeasonProfile.get(2).getType(), childSeasonProfile.get(2).getValue());

                        TemplateTouSeasonEntity seasonEntity = new TemplateTouSeasonEntity();
                        seasonEntity.setSeasonName(HexUtil.decodeHexStr(seasonProfileName));
                        seasonEntity.setStartTime(CustomStringUtils.formatSeasonStr(seasonStart));
                        seasonEntity.setWeekName(HexUtil.decodeHexStr(weekName));

                        seasonProfileList.add(seasonEntity);
                    }
                }
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), seasonProfileList, 600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)){
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true,600L, true);
                }
                break;
            case GetActivateCalendarTime:
                Object calendarTimeData = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                if (CosemUtils.isDateTimeString(Convert.toStr(calendarTimeData))) {
                    calendarTimeData = DateFormatUtils.format(CosemUtils.parseOctStringDataTime(Convert.toStr(calendarTimeData)), "yyyy-MM-dd HH:mm:ss");
                } else{
                    calendarTimeData = CosemUtils.parseOctStringDataTimeX(Convert.toStr(calendarTimeData));
                }
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), calendarTimeData, 600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)) {
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true, 600L, true);
                }
                break;
            case GetSpecialDays:
                List<TemplateTouSpecialDayEntity> specialDayList = new ArrayList<>();
                List<CosemData> specialDatas = cosemData.getChild();
                for (CosemData specialData : specialDatas) {
                    List<CosemData> childSeasonProfile = specialData.getChild();
                    if (childSeasonProfile.size() == 3) {
                        TemplateTouSpecialDayEntity specialDayEntity = new TemplateTouSpecialDayEntity();
                        // String index = (String) cosemXmlService.getData(childSeasonProfile.get(0).getType(), childSeasonProfile.get(0).getValue());
                        String specialdayDate = (String) cosemXmlService.getData(childSeasonProfile.get(1).getType(), childSeasonProfile.get(1).getValue());
                        specialdayDate = CosemUtils.parseOctStringDateWithWeek(specialdayDate);
                        specialDayEntity.setSpecialDayTime(specialdayDate);
                        String dayId = (String) cosemXmlService.getData(childSeasonProfile.get(2).getType(), childSeasonProfile.get(2).getValue());
                        specialDayEntity.setTouDayId(Convert.toLong(dayId));
                        specialDayList.add(specialDayEntity);
                    }
                }
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), specialDayList, 600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)) {
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true, 600L, true);
                }
                break;
            case GetFriendlyDays:
                List<TemplateTouFriendlyDayEntity> friendlyDayList = new ArrayList<>();
                List<CosemData> friendDatas = cosemData.getChild();
                for (CosemData specialData : friendDatas) {
                    List<CosemData> childSeasonProfile = specialData.getChild();
                    if (childSeasonProfile.size() == 3) {
                        TemplateTouFriendlyDayEntity specialDayEntity = new TemplateTouFriendlyDayEntity();
                        // String index = (String) cosemXmlService.getData(childSeasonProfile.get(0).getType(), childSeasonProfile.get(0).getValue());
                        String specialdayDate = (String) cosemXmlService.getData(childSeasonProfile.get(1).getType(), childSeasonProfile.get(1).getValue());
                        specialdayDate = CosemUtils.parseOctStringDateWithWeek(specialdayDate);
                        specialDayEntity.setFriendlyDayTime(specialdayDate);
                        String dayId = (String) cosemXmlService.getData(childSeasonProfile.get(2).getType(), childSeasonProfile.get(2).getValue());
                        specialDayEntity.setTouDayId(Convert.toLong(dayId));
                        friendlyDayList.add(specialDayEntity);
                    }
                }
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), operationName.getName(), friendlyDayList, 600L, true);
                if (isSubTaskGroupLastAtomicTask(task, atomicTask)) {
                    taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), SUB_TASK_COMPLETED, true, 600L, true);
                }
                break;
        }
        return 1;
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        if (atomicTask.getGroupId() == OperationGroup.GetTou.getId().intValue()) {
            String stepOperationName = OperationName.forId(atomicTask.getOperationId()).getName();
            if (task.getIsODR()) {
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), stepOperationName, String.format("step %s failed, [%s]", stepOperationName, message), 3600l, false);
            }
        }
        return -1;
    }
}
